#include <iostream>
#include <sys/poll.h>
#include "Sock.hpp"
#include "Epoll.hpp"

static const int N = 64;

class EpollServer
{
public:
    EpollServer(uint16_t serverPort)
        :_serverPort(serverPort)
    {}

    void Init()
    {
        _sock.Socket();
        _sock.Bind(_serverPort);
        _sock.Listen();

        _epoll.creat();
    }

    void Start()
    {
        _epoll.AddEvent(_sock.Fd(),EPOLLIN);
        while(true)
        {
            int timeout = 1000;
            int n = _epoll.wait(_env,N,timeout);
            if(n == 0)
            {
                LogMessage(Debug,"timeout");
            }
            else if(n < 0)
            {
                LogMessage(Debug,"poll fail,%s,%d",strerror(errno),errno);
                break;
            }
            else
            {
                std::cout << "有一个事件就绪" << std::endl;
                HandlerEvent();
            }
        }
    }

    void HandlerEvent()
    {
        for(int i = 0; i < N; ++i)
        {
            if(_env[i].events & EPOLLIN)//读事件
            {
                if(_env[i].data.fd == _sock.Fd())
                {
                    Accepter();
                }
                else
                {
                    Recver(_env[i].data.fd);
                }
            }
            else if(_env[i].events & EPOLLOUT)//写事件
            {
                //TODO
            }
            else//其他事件
            {
                //TODO
            }
        }
    }

    void Accepter()
    {
        std::string clientIp;
        uint16_t clientPort;
        int sock = _sock.Accept(&clientIp,&clientPort);
        if(sock > 0)
            LogMessage(Debug,"%s-%d accept success",clientIp.c_str(),clientPort);
        //_epoll.AddEvent(_sock.Fd(),EPOLLIN | EPOLLOUT);
        _epoll.AddEvent(sock,EPOLLIN);
    }

    void Recver(int sock)
    {
        char buffer[1024];
        int n = recv(sock,buffer,sizeof(buffer)-1,0);
        if(n > 0)
        {
            buffer[n] = '\0';
            std::cout << "client send# " << buffer << std::endl;
            std::string message = "server send# ";
            message += buffer;
            send(sock,message.c_str(),message.size(),0);
        }
        else if(n < 0)
        {
            LogMessage(Debug,"recv fail,%s,%d",strerror(errno),errno);
            Close(sock);
        }
        else
        {
            LogMessage(Debug,"client exit");
            Close(sock);
        }
    }

    void Close(int sock)
    {
        close(sock);
    }

    ~EpollServer()
    {
        _sock.Close();
    }
private:
    Sock _sock;
    Epoll _epoll;
    uint16_t _serverPort;
    struct epoll_event _env[N];
};
